import { StorageUtil } from './../../Util/StorageUtil';

/*
 * @features: 功能
 * @description: 说明
 * @Date: 2020-10-22 22:15:59
 * @Author: judu233(769471424@qq.com)
 * @LastEditTime: 2020-11-06 22:45:12
 * @LastEditors: judu233
 */
import { I_DrawInfo, I_MapDataArr, I_MapRelationship, I_MapSave } from './IMapType';
import z from "../../Manager/Z";
import { I_LinePoint, I_MapButtonData, I_MapData, I_MapEventData, I_MapInitData, I_Pos } from "./IMapType";
import { json, object } from 'is';

/**存储按钮数据的名字 */
export const MAP_BTN_DATA_NAME = `$btnData$`;
/**记录线条的特殊链接符号 --lineDrawedMap*/
const MAP_LINE_CONTENT = `@`;
/**存储数据的key */
const MAP_SAVE_KEY_NAME = `[test]`;

/**
 *   MapContrl控制
 */
export default class MapContrl {
    /**地图数据 */
    public data: I_MapData;
    /**是否已经走到终点 */
    public isEnd: boolean = false;
    /**控制是否能点击的 开关 */
    public isCanClick: boolean = true;

    /**
     * 初始化
     * @param mapData  地图数据
     */
    constructor(mapData?: I_MapInitData) {
        if (is.undefined(mapData)) return;

        this.data = <I_MapData>mapData;
        this.data.lineDrawedMap = new Map();
        this.data.btnDrawedMap = new Map();
        this.data.deliveryMap = new Map();
        this.data.btnClickList = [];
        // this.data.btnVisitedList = [];
        this.data.symbol = is.undefined(mapData.symbol) ? `-` : mapData.symbol;
        this.data.isObliqueDirection = is.undefined(mapData.isObliqueDirection) ? true : mapData.isObliqueDirection;
        this.data.isPositiveDirection = is.undefined(mapData.isPositiveDirection) ? true : mapData.isPositiveDirection;

        //初始化数据和关系图
        this.initMapData(mapData.dataArr);
        this.initMapRelationship(mapData.dataArr);

        //判断第一个按钮是否为空 == 0
        let startPos = mapData.startPos;
        let endPos = mapData.endPos;
        if (mapData.dataArr[startPos.x][startPos.y] == 0 || mapData.dataArr[endPos.x][endPos.y] == 0) {
            cc.error(`[初始化地图错误]：设置的开始和结束位置值为0`);
        }
        this.data.startBtn = this.createBtnInfo(startPos).info;
        this.data.nowClickBtn = this.data.startBtn;
    }

    /**
     * 生成数据对象事件
     * @param mapData  地图数据
     */
    public initMapData(mapData: I_MapDataArr) {
        // 事件数据 
        let len = mapData.length;
        let eventArr = Array.from({ length: len }, () => new Array(len));
        for (let i = 0; i < len; i++) {
            for (let j = 0; j < len; j++) {
                eventArr[i][j] = <I_MapEventData>{
                    type: mapData[i][j],
                    name: this.getPosName(i, j),
                    triggerData: {},
                    isRepeatTrigger: false,
                    canTriggerCounts: 1,
                    nowTriggerCounts: 0,
                    triggerEvent: function () {
                        if (z.debug)
                            cc.log(`[事件]${(this as I_MapEventData).name}被触发。`);
                    },
                    isLock: false,
                    lockEvent: function () {
                        if (z.debug)
                            cc.log(`被锁住了！！`);
                    },
                    isRepeatMove: true,
                    canMoveCounts: 2,
                    nowMoveCounts: 0,
                };
            }
        }
        this.data.dataList = eventArr;
        // cc.log(eventArr);
        return eventArr;
    }

    /**
     * 根据map初始化关系图
     * @param map 初始化map的关系图
     * @param isPositiveDirection 是否记录正方向图
     * @param isObliqueDirection 是否记录斜方向图
     */
    public initMapRelationship(map: I_MapDataArr, isPositiveDirection = this.data.isPositiveDirection, isObliqueDirection = this.data.isPositiveDirection) {
        let len = map.length;
        let relationshipList: Map<string, I_MapRelationship[]> = new Map(); //填充数组

        //存储关系map
        let waitSetArr: I_MapRelationship[];
        let setMapArr = (nowName: string, nextName: string, nowPosArr: I_Pos, nextPosArr: I_Pos) => {
            //存储当前的--如果为空创建-否则存储
            waitSetArr = relationshipList.get(nowName);
            if (is.undefined(waitSetArr)) waitSetArr = relationshipList.set(nowName, []).get(nowName);
            waitSetArr.push({ startPos: nowPosArr, endPos: nextPosArr, isDraw: true });

            //存储next的--如果为空创建-否则存储
            waitSetArr = relationshipList.get(nextName);
            if (is.undefined(waitSetArr)) waitSetArr = relationshipList.set(nextName, []).get(nextName);
            waitSetArr.push({ startPos: nextPosArr, endPos: nowPosArr, isDraw: true });
        };

        /**连接符 */
        /**变量 */
        let now: number, right: number, down: number, leftDown: number, rightDown: number;
        /**判断 */
        let isRight: boolean, isDown: boolean, isRightDown: boolean, isLeftDown: boolean;
        /**获取关系对象 */
        let getPosRela = (x: number, y: number) => ({ x, y });

        //查找关系
        let boundrany = len - 1;//边界
        for (let i = 0; i < len; i++) {
            for (let j = 0; j < len; j++) {
                //最后一个元素不比较
                if (i == boundrany && j == boundrany) continue;

                //获取判断值
                isRight = j < boundrany;
                isDown = i < boundrany;
                isRightDown = (j < boundrany && i < boundrany);
                isLeftDown = (j > 0 && i < boundrany);

                //获取存储值
                now = map[i][j];
                right = isRight ? map[i][j + 1] : undefined;
                down = isDown ? map[i + 1][j] : undefined;
                leftDown = isLeftDown ? map[i + 1][j - 1] : undefined;
                rightDown = isRightDown ? map[i + 1][j + 1] : undefined;

                //当前值为0跳过
                if (now == 0) continue;

                //正方向判断
                if (isPositiveDirection) {
                    //比较左右是否相通
                    if (isRight && right != 0) {
                        setMapArr(this.getPosName(i, j), this.getPosName(i, j + 1), getPosRela(i, j), getPosRela(i, j + 1));
                    }
                    //比较上下是否相同
                    if (isDown && down != 0) {
                        setMapArr(this.getPosName(i, j), this.getPosName(i + 1, j), getPosRela(i, j), getPosRela(i + 1, j));
                    }
                }
                //斜方向判断
                if (isObliqueDirection) {
                    //左斜下方
                    if (isLeftDown && leftDown != 0) {
                        setMapArr(this.getPosName(i, j), this.getPosName(i + 1, j - 1), getPosRela(i, j), getPosRela(i + 1, j - 1));
                    }
                    //右斜下方
                    if (isRightDown && rightDown != 0) {
                        setMapArr(this.getPosName(i, j), this.getPosName(i + 1, j + 1), getPosRela(i, j), getPosRela(i + 1, j + 1));
                    }
                }
            }
        }
        this.data.relationshipList = relationshipList;
        // cc.log(relationshipList);
        return relationshipList;
    }

    public saveData() {
        let d = this.data;
        let saveData = <I_MapData & I_MapSave>{
            name: d.name,
            id: d.id,
            dataArr: d.dataArr,
            startPos: d.startPos,
            endPos: d.endPos,
            centerPos: d.centerPos,
            height: d.height,
            width: d.width,
            symbol: d.symbol,
            isPositiveDirection: d.isPositiveDirection,
            isObliqueDirection: d.isObliqueDirection,
        };
        /**处理按钮上带的数据事件 */
        let getEventString = (e: I_MapEventData) => {
            let eData = Object.assign({}, e);
            eData.triggerString = e.triggerEvent.toString();
            eData.lockEventString = e.lockEvent.toString();
            return JSON.stringify(eData);
        };
        /**处理按钮引用 */
        let processBtnData = (btnData: I_MapButtonData) => {
            let bData = Object.assign({}, btnData);
            bData.btn = null;
            bData.dataString = getEventString(btnData.data);
            bData.relationshipString = JSON.stringify(btnData.relationship);
            return JSON.stringify(bData);
        };

        //存储按钮数据
        saveData.startBntString = processBtnData(d.startBtn);
        saveData.nowBtnString = processBtnData(d.nowClickBtn);
        saveData.lastBtnString = processBtnData(d.lastClickBtn);

        //存储dataList --地图数据
        let dataList: string[][] = [];
        d.dataList.forEach((d1, i1) => {
            dataList[i1] = [];
            d1.forEach((d2, i2) => {
                dataList[i1][i2] = getEventString(d2);
            });
        });
        saveData.dataListString = JSON.stringify(dataList);

        //存储传送信息
        saveData.deliveryString = JSON.stringify([...d.deliveryMap]);
        //存储关系图
        saveData.relationshipString = JSON.stringify([...d.relationshipList]);
        //存储绘制线条信息
        saveData.lineDrawedString = JSON.stringify([...d.lineDrawedMap]);

        //存储已经绘制的按钮信息
        let btnDrawesList: [string, string][] = [];
        d.btnDrawedMap.forEach((bData, key) => {
            btnDrawesList.push([key, processBtnData(bData)]);
        });
        saveData.btnDrawesString = JSON.stringify(btnDrawesList);

        //存储点击列表
        let clickList: string[] = [];
        d.btnClickList.forEach(b3 => {
            clickList.push(processBtnData(b3));
        });
        saveData.btnClickString = JSON.stringify(clickList);

        //存储
        StorageUtil.setLocalItemImmediately(MAP_SAVE_KEY_NAME, saveData);
    }

    public loadData() {
        //加载
        let mapDataString = StorageUtil.getLocalItem(MAP_SAVE_KEY_NAME);
        if (is.undefined(mapDataString)) {
            cc.log(`[加载地图数据]：加载的数据为空！`);
            return;
        }
        let mapData = JSON.parse(mapDataString) as I_MapSave & I_MapData;
        //反序列化数据
        this.data = mapData;
        /**处理按钮上带的数据事件 */
        let getEventObj = (e: string) => {
            let eObj = JSON.parse(e) as I_MapEventData;
            let evalString = `eObj.triggerEvent =`;
            eval(evalString + eObj.triggerString);
            eObj.triggerEvent.bind(eObj);
            //锁住事件
            evalString = `eObj.lockEvent =`;
            eval(evalString + eObj.lockEventString);
            eObj.lockEvent.bind(eObj);
            return eObj;
        };
        /**处理按钮引用 */
        let processBtnData = (bStr: string) => {
            let bObj = JSON.parse(bStr) as I_MapButtonData;
            bObj.data = getEventObj(bObj.dataString);
            bObj.relationship = JSON.parse(bObj.relationshipString);
            //设置按钮--并添加到场景
            let btnNode =z.mapDraw.creatorBtn();
            this.bindBtn(btnNode, bObj.x, bObj.y);
            bObj.btn = btnNode;
            return bObj;
        };

        //获取数据
        let dataList: string[][] = JSON.parse(mapData.dataListString);
        mapData.dataList = [];
        dataList.forEach((d1, i1) => {
            mapData.dataList[i1] = [];
            d1.forEach((d2, i2) => {
                mapData.dataList[i1][i2] = getEventObj(d2);
            });
        });

        //获取传送信息
        mapData.deliveryMap = new Map(JSON.parse(mapData.deliveryString));
        //获取关系图
        mapData.relationshipList = new Map(JSON.parse(mapData.relationshipString));
        //获取绘制线条信息
        mapData.lineDrawedMap = new Map(JSON.parse(mapData.lineDrawedString));

        //获取按钮数据
        mapData.startBtn = processBtnData(mapData.startBntString);
        mapData.nowClickBtn = processBtnData(mapData.nowBtnString);
        mapData.lastClickBtn = processBtnData(mapData.lastBtnString);


        //获取已经绘制的按钮信息
        let btnDrawesList: [string, string][] = JSON.parse(mapData.btnDrawesString);
        mapData.btnDrawedMap = new Map();
        btnDrawesList.forEach(([key, data]) => {
            mapData.btnDrawedMap.set(key, processBtnData(data));
        });

        //存储点击列表
        let clickList: string[] = JSON.parse(mapData.btnClickString);
        mapData.btnClickList = [];
        clickList.forEach(b3 => {
            mapData.btnClickList.push(processBtnData(b3));
        });
        cc.log(this.data);
    }

    /**
     * 获取基于行列的链接符名字 
     * @param i 行位置
     * @param j 列位置
     */
    public getPosName(i: number, j: number) { return `${i + this.data.symbol + j}`; }

    /** 获取设定的中间按钮位置--用于结束时俯视地图 */
    public getCenterMapPos() {
        let p = this.data.centerPos;
        let v3 = cc.v3(p.y * this.data.width, -p.x * this.data.height)
        let centerNode = new cc.Node(`centerNode`);
        centerNode.setPosition(v3);
        z.mapDraw.node.addChild(centerNode);
        return centerNode;
    }

    /**
     * 获取根据地图数据上对应游戏中地图中的节点位置
     * @param x 地图数据 x
     * @param y 地图数据
     */
    public getBtnPos(i: number, j: number) { return cc.v3(j * this.data.width, -i * this.data.height); }

    /**
     *  创建一个按钮数据
     * @param initPos  初始位置--> 数据地图的x,y
     * @param initData 初始数据
     */
    public createBtnInfo(pos: number | I_Pos, y?: number): { info: I_MapButtonData, isDraw: boolean } {
        let x: number;
        //判断参数
        if (is.not.number(pos)) {
            ({ x, y } = (pos as I_Pos));
        } else x = (pos as number);

        //检查按钮是否存在，如果存在就不创建，否则直接读取返回
        let nowBtnInfo = this.data.btnDrawedMap.get(this.getPosName(x, y));
        if (is.not.undefined(nowBtnInfo)) return { info: nowBtnInfo, isDraw: true };

        //创建按钮,判断是否能创建
        let btn = z.mapDraw.creatorBtn();
        if (is.undefined(btn)) {
            cc.warn(`[创建按钮]: 按钮${btn.name}预制体根节点没有添加cc.Button组件`);
            return;
        }

        //设置按钮数据和事件
        let btnData = this.bindBtn(btn, x, y);
        this.data.btnDrawedMap.set(this.getPosName(x, y), btnData);

        return { info: btnData, isDraw: false };
    }

    /**
     * 绑定按钮事件和数据 
     * @param btn 按钮组件
     * @param x 地图数据x
     * @param y 地图数据y
     */
    public bindBtn(btn: cc.Button, x: number, y: number) {
        //设置按钮数据
        let btnData = <I_MapButtonData>{
            x, y, btn, data: this.data.dataList[x][y],
            relationship: this.data.relationshipList.get(this.getPosName(x, y)),
        };
        // 设置节点名字
        btn.node.name = this.getPosName(x, y);

        //设置点击事件
        let comName = /<[a-z,A-Z,0-9]*>/.exec(z.mapDraw.name)[0].replace(/^(\s|<)+|(\s|>)+$/g, ''); // mapDraw组件名字
        let eventHandle = new cc.Component.EventHandler();
        eventHandle.target = z.mapDraw.node;
        eventHandle.component = comName;
        eventHandle.handler = `btnClickEvent`;
        btn.clickEvents.push(eventHandle);

        //设置按钮位置，并添加到场景
        btn.node.setPosition(this.getBtnPos(x, y));
        z.mapDraw.node.addChild(btn.node);
        btn.node.active = false;

        //绑定按钮数据
        btn[MAP_BTN_DATA_NAME] = btnData;

        return btnData;
    }

    /**
     * 点击按钮触发的事件（mapDraw必须继承接口并实现）,并返回是否能移动
     * @param event 按钮触发的事件
     * @param btnInfo 按钮信息 或按钮
     * @param isDelivery  是否是传送
     */
    public clickBtn(event: cc.Event, btnInfo: I_MapButtonData | cc.Button, isDelivery = true) {
        if (this.isEnd || !this.isCanClick) return false; //结束直接返回

        /**
         *  判断逻辑： 
         *      点击情况： 1.第一次点击--> 点击开始按钮和未存储过的其他按钮 -->  lastClick = null
         *                2.非第一点击--> 点击当前按钮和未存储过的按钮， 已经存储过的按钮  
         *      操作： 不记录当前正处的位置， 
         */

        let clickBtn = btnInfo instanceof cc.Button ? (btnInfo as cc.Button) : (btnInfo as I_MapButtonData).btn;
        let clickInfo = clickBtn[MAP_BTN_DATA_NAME] as I_MapButtonData;
        let nowClickBtn = this.data.nowClickBtn;

        //判断是否可以点击
        if (!this.checkIsCanClick(clickInfo)) return false;

        //触发锁住判定===--如果锁住触发事件
        let eventData = clickInfo.data;
        if (eventData.isLock) {
            eventData.lockEvent(event, clickInfo);
            if (z.debug)
                cc.log(`【🕹锁住判定】：${eventData.name}按钮已被锁住！`);
            return false;
        }

        //触发移动判定
        if (!eventData.isRepeatMove && eventData.canMoveCounts <= eventData.nowMoveCounts)
            return false;
        else if (!eventData.isRepeatMove) {
            eventData.nowMoveCounts++;
            if (z.debug)
                cc.log(`【⛸移动判定】: ${eventData.name}已经移动${eventData.nowMoveCounts}次, 总共可以移动${eventData.canMoveCounts}次`);
        }

        //触发自定义事件
        if (eventData?.triggerEvent) {
            let isRepeat = eventData.isRepeatTrigger;

            //可以重复触发，或者在限定次数内
            if (isRepeat || (!isRepeat && eventData.nowTriggerCounts < eventData.canTriggerCounts)) {
                eventData.nowTriggerCounts++;
                eventData.triggerEvent(event, clickInfo, eventData.triggerData);
                if (z.debug)
                    cc.log(`【🎗自定义事件判定】: ${eventData.name}已经触发事件${eventData.nowTriggerCounts}次, 总共可以触发${eventData.canTriggerCounts}次`);
            }
        }

        //判断是否是传送点
        let delivery = this.data.deliveryMap.get(clickInfo.data.name);
        if (delivery && isDelivery) {
            let endPos = delivery.endPos;
            cc.log(`即将被进入传送点,将被传送到${endPos.x},${endPos.y}`);
            z.mapDraw.scheduleOnce(() => {
                cc.log(`开始准备传送`);
                let nextBtnData = this.data.btnDrawedMap.get(this.getPosName(endPos.x, endPos.y));
                this.clickBtn(undefined, nextBtnData, false)
                    && z.camera.updateCamera(nextBtnData.btn.node.position, this.data.lastClickBtn.btn.node.position);
            }, 2);
        }


        //设置当前点击的按钮
        this.data.lastClickBtn = nowClickBtn;
        this.data.nowClickBtn = clickInfo;

        //设置点击效果
        // clickInfo.btn.node.scale = 1.5;
        // nowClickBtn.btn.node.scale = 1;
        clickInfo.btn.node.getChildByName(`blight`).active = true;
        nowClickBtn.btn.node.getChildByName(`blight`).active = false;

        //判断是否是结束按钮
        if (this.btnIsEqual(clickInfo, this.data.endPos)) {
            if (z.debug)
                cc.log(`[到达终点]`);
            this.isEnd = true;
            z.camera.outCamera(this.getCenterMapPos());
            return false;
        }

        //绘制
        z.mapDraw.drawMap(this.getNextDrawInfo(clickBtn));

        if (z.debug) {
            cc.log(`---------------地图按钮和线条数量--------------------------`);
            cc.log(`[btnMapSize]: ${this.data.btnDrawedMap.size}`);
            cc.log(`[lineMapSize]: ${this.data.lineDrawedMap.size}`);
        }
        return true;
    }

    /**
     * 检查当前点击是否生效【基础判定】
     * @param clickInfo 当前点击信息
     */
    public checkIsCanClick(clickInfo: I_MapButtonData) {
        //如果点击同一个按钮不记录
        let lastClickBtn = this.data.lastClickBtn;
        let nowClickBtn = this.data.nowClickBtn;

        //点击同一个按钮
        if (this.btnIsEqual(nowClickBtn, clickInfo)) return false;

        //判断距离是否可以点击, 只能点击周围按钮--不能点击相隔1个以上的按钮
        //查询关系图
        let relationship = nowClickBtn.relationship;
        let isInterval = relationship.some(({ startPos, endPos }) => this.btnIsEqual(endPos, clickInfo));

        //不是存储在关系map里的--不能点击
        if (!isInterval) return false;

        //第一次点击
        if (is.undefined(lastClickBtn)) {
            //存储当前点击到访问列表--应用于其他全局判断--比如计数等等
            this.data.btnClickList.push(clickInfo);
        } else if (this.findIsClicked(clickInfo)) {
            //存在，已经点击过

        }

        return true;
    }

    /**
     * 根据按钮获取下一步操作信息
     * @param btn 按钮组件
     */
    public getNextDrawInfo(btn: cc.Button): I_DrawInfo {
        let nowBtnInfo = btn[MAP_BTN_DATA_NAME] as I_MapButtonData;
        let nowBtn = nowBtnInfo.btn;
        let relationship = nowBtnInfo.relationship; //关系

        //绘制信息列表
        let btnInfoList: I_MapButtonData[] = []; //绘制按钮信息
        let lineList: I_LinePoint[] = []; //要绘制的线

        for (let [index, { startPos, endPos, isDraw }] of relationship.entries()) {
            //判断是否已经绘制了按钮
            let next = this.createBtnInfo(endPos);
            let nextBtn = next.info.btn;
            if (!next.isDraw) {
                nextBtn.node.active = false;
                btnInfoList.push(next.info);
            }

            //判断是否需要绘制
            if (!isDraw) continue;

            //获取按钮间的连线列表
            if (z.debug) {
                cc.log(`----【线条绘制】：x:${nowBtnInfo.x}--y:${nowBtnInfo.y}--------`);
                cc.log(`[节点位置start]: x:${nowBtnInfo.btn.node.x},y:${nowBtnInfo.btn.node.y}`);
                cc.log(`[节点位置end]: x:${next.info.btn.node.x},y:${next.info.btn.node.y}`);
                cc.log(`[地图数据]:x:${next.info.x}--y:${next.info.y}--------`);
                cc.log(`-------------------`);
            };

            //判断是否已经绘制过该线条
            let lineInfo: I_LinePoint;
            let getLineName = (nowInfo: I_MapButtonData, nextInfo: I_MapButtonData) => {
                let nowName = this.getPosName(nowInfo.x, nowInfo.y);
                let nextName = this.getPosName(nextInfo.x, nextInfo.y);
                return nowName + MAP_LINE_CONTENT + nextName;
            };
            /**a -> b 的线条 */
            let nextLineName = getLineName(nowBtnInfo, next.info);
            let nextLineOne = this.data.lineDrawedMap.get(nextLineName);
            /**b -> a 的线条 */
            nextLineName = getLineName(next.info, nowBtnInfo);
            let nextLineTwo = this.data.lineDrawedMap.get(nextLineName);
            //是否已经绘制或正在绘制
            let isDrawed = is.not.undefined(nextLineOne) || is.not.undefined(nextLineTwo);

            if (!isDrawed) {
                //转换线条绘制坐标
                let drawNode = z.drawComList[index]?.node;
                if (is.undefined(drawNode)) { cc.log(`[获取绘制信息出错]:没有${index}的序号画线组件！`); return; }
                let startPos = drawNode.convertToNodeSpaceAR(nowBtn.node.convertToWorldSpaceAR(cc.v3(0, 0, 0)));
                let endPos = drawNode.convertToNodeSpaceAR(nextBtn.node.convertToWorldSpaceAR(cc.v3(0, 0, 0)));

                //存储线条信息-以判断和绘制
                lineInfo = <I_LinePoint>{ startPos, endPos, step: 10, drawInterval: 0.03, id: Mock.Random.guid() };
                lineList.push(lineInfo);

                this.data.lineDrawedMap.set(nextLineName, lineInfo);
            }
        }

        return { btnInfoList, lineList };
    }

    /**
     * 根据存储数据获取绘制按钮和线条（确保场景不要有任何按钮和线条，否则会重复绘制）
     */
    public getLoadDrawInfo(): I_DrawInfo {
        //绘制信息列表
        let btnInfoList: I_MapButtonData[] = [...this.data.btnDrawedMap.values()];
        let lineList: I_LinePoint[] = [...this.data.lineDrawedMap.values()]; //要绘制的线
        return { btnInfoList, lineList };
    }

    /**
     * 适用：传送功能
     * 设置开始位置到结束位置的特殊关系线--并添加到Map里
     * @param startPos 开始位置
     * @param endPos 结束位置
     * @param isDraw 是否绘制线条
     */
    public setBtnRelationship(nowPosArr: I_Pos, nextPosArr: I_Pos, isDraw = false) {
        try {
            let nowName = this.getPosName(nowPosArr.x, nowPosArr.y);
            let nextName = this.getPosName(nextPosArr.x, nextPosArr.y);
            this.data.relationshipList.get(nowName).push({ startPos: nowPosArr, endPos: nextPosArr, isDraw: isDraw });
            this.data.relationshipList.get(nextName).push({ startPos: nextPosArr, endPos: nowPosArr, isDraw: isDraw });
            this.data.deliveryMap.set(nowName, { startPos: nowPosArr, endPos: nextPosArr });
            this.data.deliveryMap.set(nextName, { startPos: nextPosArr, endPos: nowPosArr });
        } catch (error) {
            cc.error(`[设置特殊关系数据错误]: 开始：${nowPosArr}, 结束：${nextPosArr}`, error);
        }
    }

    /**
     * 判断2个按钮是否相等
     * @param first 第一个按钮
     * @param last 第二个按钮
     */
    private btnIsEqual(first: I_MapButtonData | I_Pos, last: I_MapButtonData | I_Pos) {
        return first.x == last.x && first.y == last.y;
    }

    /**
     * 根据info查找点击列表是否已经存在
     * @param info 要查找的按钮信息
     */
    private findIsClicked(info: I_MapButtonData) {
        return this.data.btnClickList.some(btnInfo => this.btnIsEqual(btnInfo, info));
    }

}